package sim;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.swing.JComponent;

import obj.Edge;
import obj.Junction;
import obj.Node;
import obj.Path;

public class VehicleComponent extends JComponent {

	private static final long serialVersionUID = 7485241675736966701L;
	private volatile List<Vehicle> vehiclesList = new ArrayList<Vehicle>();
	private List<Junction> junctionList = new ArrayList<Junction>();
	private Set<Node> allJunctionNodes = new HashSet<Node>();
	private List<Node> greenNodes = new ArrayList<Node>();
	public static final int TILE_SIZE = 10;

	public synchronized void add(Vehicle vehicle) {
		vehiclesList.add(vehicle);
	}

	public void addJunctions(List<Junction> list) {
		this.junctionList = list;

	}

	public void addNodes(Set<Node> allJunctionNodesList) {
		this.allJunctionNodes = allJunctionNodesList;
	}

	public void addGreenNodes(List<Node> phaseList) {
		this.greenNodes = phaseList;
	}

	public void paintComponent(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;
		List<Vehicle> vList = new ArrayList<Vehicle>();
		vList.addAll(vehiclesList);
		/*
		 * Draw Paths
		 */
		for (Vehicle vehicle : vList) {

			g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

			g2.setColor(Color.DARK_GRAY);
			g2.setStroke(new BasicStroke(14.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND));

			Path2D.Double s = getPathShape(vehicle.getPath());
			g2.draw(s);
			g2.setColor(Color.lightGray);
			g2.setStroke(new BasicStroke(12.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND));
			g2.draw(s);

			// g2.setPaint(Color.WHITE);
			// g2.fillOval(vehicle.getPath().getEdgesList().get(0).getStartNode().getxPoint(),
			// vehicle.getPath()
			// .getEdgesList().get(0).getStartNode().getyPoint(), 8, 8);
			// g2.fillOval(vehicle.getPath().getEdgesList().get(0).getEndNode().getxPoint(),
			// vehicle.getPath()
			// .getEdgesList().get(0).getEndNode().getyPoint(), 8, 8);

		}
		/*
		 * Draw cars
		 */
		for (Vehicle vehicle : vList) {

			g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			g2.setStroke(new BasicStroke(12.0f));
			g2.setPaint(Color.BLACK);
			g2.draw(vehicle.getShape());
			g2.setStroke(new BasicStroke(8.0f));
			g2.setPaint(vehicle.getColor());
			g2.draw(vehicle.getShape());
			if ("path4".equals(vehicle.getPath().getName())) {
				g2.setPaint(Color.WHITE);
				String[] arr = vehicle.getName().split("_");
				g2.drawString(arr[1], (int) vehicle.getX(), (int) vehicle.getY());
			}

		}

		/*
		 * Draw Nodes
		 */
		for (Node n : allJunctionNodes) {
			g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			g2.setColor(Color.RED);
			g2.setStroke(new BasicStroke(1));
			g2.drawOval(n.getxBox() * TILE_SIZE, n.getyBox() * TILE_SIZE, TILE_SIZE, TILE_SIZE);
			g2.fillOval(n.getxBox() * TILE_SIZE, n.getyBox() * TILE_SIZE, TILE_SIZE, TILE_SIZE);
		}

		/*
		 * Draw Green Nodes
		 */
		for (Node n : greenNodes) {
			g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			g2.setColor(Color.GREEN);
			g2.setStroke(new BasicStroke(1));
			g2.drawOval(n.getxBox() * TILE_SIZE, n.getyBox() * TILE_SIZE, TILE_SIZE, TILE_SIZE);
			g2.fillOval(n.getxBox() * TILE_SIZE, n.getyBox() * TILE_SIZE, TILE_SIZE, TILE_SIZE);
		}

	}

	private Path2D.Double getPathShape(Path p) {
		Path2D.Double pathShape;
		List<Path2D.Double> shapesList = new ArrayList<Path2D.Double>();
		pathShape = new Path2D.Double();
		List<Edge> edges = p.getEdgesList();
		int count = 0;
		double[] xpoints = new double[edges.size() * 2];
		double[] ypoints = new double[edges.size() * 2];
		double xValue;
		double yValue;

		for (Edge e : edges) {
			Node sNode = e.getStartNode();
			xValue = sNode.getxDouble();
			yValue = sNode.getyDouble();
			xpoints[count] = xValue;
			ypoints[count] = yValue;
			count++;
			Node eNode = e.getEndNode();
			xValue = eNode.getxDouble();
			yValue = eNode.getyDouble();
			xpoints[count] = xValue;
			ypoints[count] = yValue;
			count++;
		}

		for (int i = 0; i < xpoints.length; i++) {
			if (i == 0) {
				pathShape.moveTo(xpoints[i], ypoints[i]);
			} else {
				pathShape.lineTo(xpoints[i], ypoints[i]);
			}
		}

		shapesList.add(pathShape);

		return pathShape;
	}
}
